import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;



public class StringParseTest {

	public static void main(String[] args) {
		
		int processedCount = processIncomingFile(new File("WeeklyDisability.txt"));
		System.out.println("********* processed count: " + processedCount);
	}
	
	private static int processIncomingFile(File incomingFile) {
		
		BufferedReader br = null;
		try {
			br = new BufferedReader(new FileReader(incomingFile));
		} catch (FileNotFoundException fnfe) {
			fnfe.printStackTrace();
			return 0;
		}

		int processedRecordCount = 0;
		String line = null;

////
		try {
			line = br.readLine();
		} catch (IOException ioe) {
			System.err.println(ioe.getMessage());
			// TODO: log the error message: file could not be processed due to IO Error while reading
			
			// in case of IOException while reading the first line
			// log the error message and then just return.
			return 0;
		}

		// If you put try catch block outside of while loop,
		// in case of exception the remaining lines don't get processed.
		
		// Now line variable has the first line of the file. 
		
		do {
			String filename = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_IMAGE_FILENAME);
			String scanLocation = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_IMAGE_SCAN_LOCATION);
			String imageType = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_IMAGE_TYPE);
			String ownerClass = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_OWNER_CLASS);
			String v3Entity = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_V3_ENTITY);
			String v3Index = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_V3_INDEX);
			String searchAttribute1 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_1);
			String searchAttribute2 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_2);
			String searchAttribute3 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_3);
			String searchAttribute4 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_4);
			String searchAttribute5 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_5);
			String searchAttribute6 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_6);
			String v3InternalId = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_V3_INTERNAL_ID);
			
			processedRecordCount++;
			
			System.out.println("filename: " + filename + 
					", scanLocation: " + scanLocation +
					", imageType: " + imageType +
					", ownerClass: " + ownerClass +
					", v3Entity: " + v3Entity +
					", v3Index: " + v3Index +
					", searchAttribute1: " + searchAttribute1 +
					", searchAttribute2: " + searchAttribute2 +
					", searchAttribute3: " + searchAttribute3 +
					", searchAttribute4: " + searchAttribute4 +
					", searchAttribute5: " + searchAttribute5 +
					", searchAttribute6: " + searchAttribute6 +						
					", v3InternalId: " + v3InternalId);
			
			try {
				line = br.readLine();				
			} catch (IOException ioe) {
				// TODO: handle exception and return	
				System.err.println(ioe);
			}
		} while (line != null);
		

		try {
			if (br != null)
				br.close();				
		} catch (IOException ioe) {
			// 
		}
		
		
		
//		try {
//			while ((line = br.readLine()) != null) {
//				String filename = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_IMAGE_FILENAME);
//				String scanLocation = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_IMAGE_SCAN_LOCATION);
//				String imageType = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_IMAGE_TYPE);
//				String ownerClass = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_OWNER_CLASS);
//				String v3Entity = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_V3_ENTITY);
//				String v3Index = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_V3_INDEX);
//				String searchAttribute1 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_1);
//				String searchAttribute2 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_2);
//				String searchAttribute3 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_3);
//				String searchAttribute4 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_4);
//				String searchAttribute5 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_5);
//				String searchAttribute6 = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_SEARCH_ATTRIBUTE_6);
//				String v3InternalId = IncomingFileParser.extractValue(line, IncomingFileDefinition.ATTRIB_V3_INTERNAL_ID);
//				
//				processedRecordCount++;
//				
//				System.out.println("filename: " + filename + 
//						", scanLocation: " + scanLocation +
//						", imageType: " + imageType +
//						", ownerClass: " + ownerClass +
//						", v3Entity: " + v3Entity +
//						", v3Index: " + v3Index +
//						", searchAttribute1: " + searchAttribute1 +
//						", searchAttribute2: " + searchAttribute2 +
//						", searchAttribute3: " + searchAttribute3 +
//						", searchAttribute4: " + searchAttribute4 +
//						", searchAttribute5: " + searchAttribute5 +
//						", searchAttribute6: " + searchAttribute6 +						
//						", v3InternalId: " + v3InternalId);
//				
//			}
//		} catch (IOException ioe) {
//			ioe.printStackTrace();
//			return processedRecordCount;
//		}
		
		return processedRecordCount;
	}
	
}


class FileAttribute {

	String name;
	int length;
	int beginIndex;
	
	public FileAttribute(String name, int length, int beginIndex) {
		this.name = name;
		this.length = length;
		this.beginIndex = beginIndex;
	}
}

class IncomingFileDefinition {

	static final String ATTRIB_IMAGE_FILENAME = "IMAGE_FILENAME";
	static final String ATTRIB_IMAGE_SCAN_LOCATION = "IMAGE_SCAN_LOCATION";
	static final String ATTRIB_IMAGE_TYPE = "IMAGE_TYPE";
	static final String ATTRIB_OWNER_CLASS = "OWNER_CLASS";
	static final String ATTRIB_V3_ENTITY = "V3_ENTITY";
	static final String ATTRIB_V3_INDEX = "V3_INDEX";
	static final String ATTRIB_SEARCH_ATTRIBUTE_1 = "SEARCH_ATTRIBUTE_1";
	static final String ATTRIB_SEARCH_ATTRIBUTE_2 = "SEARCH_ATTRIBUTE_2";
	static final String ATTRIB_SEARCH_ATTRIBUTE_3 = "SEARCH_ATTRIBUTE_3";
	static final String ATTRIB_SEARCH_ATTRIBUTE_4 = "SEARCH_ATTRIBUTE_4";
	static final String ATTRIB_SEARCH_ATTRIBUTE_5 = "SEARCH_ATTRIBUTE_5";
	static final String ATTRIB_SEARCH_ATTRIBUTE_6 = "SEARCH_ATTRIBUTE_6";
	static final String ATTRIB_V3_INTERNAL_ID = "V3_INTERNAL_ID";
	
	static final int COLUMN_LENGTH_IMAGE_FILENAME = 8;	
	static final int COLUMN_LENGTH_IMAGE_SCAN_LOCATION = 40;
	static final int COLUMN_LENGTH_IMAGE_TYPE = 30;
	static final int COLUMN_LENGTH_OWNER_CLASS = 1;
	static final int COLUMN_LENGTH_V3_ENTITY = 1;
	static final int COLUMN_LENGTH_V3_INDEX = 10;
	static final int COLUMN_LENGTH_SEARCH_ATTRIBUTE_1 = 10;
	static final int COLUMN_LENGTH_SEARCH_ATTRIBUTE_2 = 10;
	static final int COLUMN_LENGTH_SEARCH_ATTRIBUTE_3 = 10;
	static final int COLUMN_LENGTH_SEARCH_ATTRIBUTE_4 = 10;
	static final int COLUMN_LENGTH_SEARCH_ATTRIBUTE_5 = 10;
	static final int COLUMN_LENGTH_SEARCH_ATTRIBUTE_6 = 10;
	static final int COLUMN_LENGTH_V3_INTERNAL_ID = 10;

	// start index = previous attribute's START_INDEX + previous attribute's COLUMN_LENGTH
	static final int START_INDEX_IMAGE_FILENAME;
	static final int START_INDEX_IMAGE_SCAN_LOCATION;
	static final int START_INDEX_IMAGE_TYPE;
	static final int START_INDEX_OWNER_CLASS;
	static final int START_INDEX_V3_ENTITY;
	static final int START_INDEX_V3_INDEX;
	static final int START_INDEX_SEARCH_ATTRIBUTE_1;
	static final int START_INDEX_SEARCH_ATTRIBUTE_2;
	static final int START_INDEX_SEARCH_ATTRIBUTE_3;
	static final int START_INDEX_SEARCH_ATTRIBUTE_4;
	static final int START_INDEX_SEARCH_ATTRIBUTE_5;
	static final int START_INDEX_SEARCH_ATTRIBUTE_6;
	static final int START_INDEX_V3_INTERNAL_ID;
	
	static final Map attributesMap;
	static {
		START_INDEX_IMAGE_FILENAME = 0;
		START_INDEX_IMAGE_SCAN_LOCATION = START_INDEX_IMAGE_FILENAME + COLUMN_LENGTH_IMAGE_FILENAME;
		START_INDEX_IMAGE_TYPE = START_INDEX_IMAGE_SCAN_LOCATION + COLUMN_LENGTH_IMAGE_SCAN_LOCATION;
		START_INDEX_OWNER_CLASS = START_INDEX_IMAGE_TYPE + COLUMN_LENGTH_IMAGE_TYPE;
		START_INDEX_V3_ENTITY = START_INDEX_OWNER_CLASS + COLUMN_LENGTH_OWNER_CLASS;
		START_INDEX_V3_INDEX = START_INDEX_V3_ENTITY + COLUMN_LENGTH_V3_ENTITY;
		START_INDEX_SEARCH_ATTRIBUTE_1 = START_INDEX_V3_INDEX + COLUMN_LENGTH_V3_INDEX;
		START_INDEX_SEARCH_ATTRIBUTE_2 = START_INDEX_SEARCH_ATTRIBUTE_1 + COLUMN_LENGTH_SEARCH_ATTRIBUTE_1;
		START_INDEX_SEARCH_ATTRIBUTE_3 = START_INDEX_SEARCH_ATTRIBUTE_2 + COLUMN_LENGTH_SEARCH_ATTRIBUTE_2;
		START_INDEX_SEARCH_ATTRIBUTE_4 = START_INDEX_SEARCH_ATTRIBUTE_3 + COLUMN_LENGTH_SEARCH_ATTRIBUTE_3;
		START_INDEX_SEARCH_ATTRIBUTE_5 = START_INDEX_SEARCH_ATTRIBUTE_4 + COLUMN_LENGTH_SEARCH_ATTRIBUTE_4;
		START_INDEX_SEARCH_ATTRIBUTE_6 = START_INDEX_SEARCH_ATTRIBUTE_5 + COLUMN_LENGTH_SEARCH_ATTRIBUTE_5;
		START_INDEX_V3_INTERNAL_ID = START_INDEX_SEARCH_ATTRIBUTE_6 + COLUMN_LENGTH_SEARCH_ATTRIBUTE_6;

		attributesMap = new HashMap();
		
		attributesMap.put(ATTRIB_IMAGE_FILENAME, 
				new FileAttribute(ATTRIB_IMAGE_FILENAME, COLUMN_LENGTH_IMAGE_FILENAME, START_INDEX_IMAGE_FILENAME));
		
		attributesMap.put(ATTRIB_IMAGE_SCAN_LOCATION, 
				new FileAttribute(ATTRIB_IMAGE_SCAN_LOCATION, COLUMN_LENGTH_IMAGE_SCAN_LOCATION, START_INDEX_IMAGE_SCAN_LOCATION));
		
		attributesMap.put(ATTRIB_IMAGE_TYPE, 
				new FileAttribute(ATTRIB_IMAGE_TYPE, COLUMN_LENGTH_IMAGE_TYPE, START_INDEX_IMAGE_TYPE));
		
		attributesMap.put(ATTRIB_OWNER_CLASS, 
				new FileAttribute(ATTRIB_OWNER_CLASS, COLUMN_LENGTH_OWNER_CLASS, START_INDEX_OWNER_CLASS));
		
		attributesMap.put(ATTRIB_V3_ENTITY, 
				new FileAttribute(ATTRIB_V3_ENTITY, COLUMN_LENGTH_V3_ENTITY, START_INDEX_V3_ENTITY));
		
		attributesMap.put(ATTRIB_V3_INDEX, 
				new FileAttribute(ATTRIB_V3_INDEX, COLUMN_LENGTH_V3_INDEX, START_INDEX_V3_INDEX));
		
		attributesMap.put(ATTRIB_SEARCH_ATTRIBUTE_1, 
				new FileAttribute(ATTRIB_SEARCH_ATTRIBUTE_1, COLUMN_LENGTH_SEARCH_ATTRIBUTE_1, START_INDEX_SEARCH_ATTRIBUTE_1));
		
		attributesMap.put(ATTRIB_SEARCH_ATTRIBUTE_2, 
				new FileAttribute(ATTRIB_SEARCH_ATTRIBUTE_2, COLUMN_LENGTH_SEARCH_ATTRIBUTE_2, START_INDEX_SEARCH_ATTRIBUTE_2));

		attributesMap.put(ATTRIB_SEARCH_ATTRIBUTE_3, 
				new FileAttribute(ATTRIB_SEARCH_ATTRIBUTE_3, COLUMN_LENGTH_SEARCH_ATTRIBUTE_3, START_INDEX_SEARCH_ATTRIBUTE_3));

		attributesMap.put(ATTRIB_SEARCH_ATTRIBUTE_4, 
				new FileAttribute(ATTRIB_SEARCH_ATTRIBUTE_4, COLUMN_LENGTH_SEARCH_ATTRIBUTE_4, START_INDEX_SEARCH_ATTRIBUTE_4));

		attributesMap.put(ATTRIB_SEARCH_ATTRIBUTE_5, 
				new FileAttribute(ATTRIB_SEARCH_ATTRIBUTE_5, COLUMN_LENGTH_SEARCH_ATTRIBUTE_5, START_INDEX_SEARCH_ATTRIBUTE_5));

		attributesMap.put(ATTRIB_SEARCH_ATTRIBUTE_6, 
				new FileAttribute(ATTRIB_SEARCH_ATTRIBUTE_6, COLUMN_LENGTH_SEARCH_ATTRIBUTE_6, START_INDEX_SEARCH_ATTRIBUTE_6));
		
		attributesMap.put(ATTRIB_V3_INTERNAL_ID, 
				new FileAttribute(ATTRIB_V3_INTERNAL_ID, COLUMN_LENGTH_V3_INTERNAL_ID, START_INDEX_V3_INTERNAL_ID));
	}
}

class IncomingFileParser {
	
	public static String extractValue(String line, String attributeName) {
		
		FileAttribute fileAttribute = (FileAttribute) IncomingFileDefinition.attributesMap.get(attributeName);		
		int beginIndex = fileAttribute.beginIndex;
		int endIndex = fileAttribute.beginIndex + fileAttribute.length;
		
		if (beginIndex < 0 || beginIndex > endIndex || beginIndex > line.length()-1 || endIndex > line.length())
			return null;
		
		return line.substring(beginIndex, endIndex).trim();
	}
	
}
